home *** CD-ROM | disk | FTP | other *** search
/ Aminet 15 / Aminet 15 - Nov 1996.iso / Aminet / dev / lang / FPL_v147.lha / fpl / src / reference.c < prev    next >
C/C++ Source or Header  |  1996-08-06  |  9KB  |  290 lines

  1. /******************************************************************************
  2.  *              FREXX PROGRAMMING LANGUAGE                  *
  3.  ******************************************************************************
  4.  
  5.  Reference.c
  6.  
  7.  Routines for interpreting variable references from the interface function.
  8.  
  9.  *****************************************************************************/
  10.  
  11. /************************************************************************
  12.  *                                                                      *
  13.  * fpl.library - A shared library interpreting script langauge.         *
  14.  * Copyright (C) 1992-1994 FrexxWare                                    *
  15.  * Author: Daniel Stenberg                                              *
  16.  *                                                                      *
  17.  * This program is free software; you may redistribute for non          *
  18.  * commercial purposes only. Commercial programs must have a written    *
  19.  * permission from the author to use FPL. FPL is *NOT* public domain!   *
  20.  * Any provided source code is only for reference and for assurance     *
  21.  * that users should be able to compile FPL on any operating system     *
  22.  * he/she wants to use it in!                                           *
  23.  *                                                                      *
  24.  * You may not change, resource, patch files or in any way reverse      *
  25.  * engineer anything in the FPL package.                                *
  26.  *                                                                      *
  27.  * This program is distributed in the hope that it will be useful,      *
  28.  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
  29.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                 *
  30.  *                                                                      *
  31.  * Daniel Stenberg                                                      *
  32.  * Ankdammsgatan 36, 4tr                                                *
  33.  * S-171 43 Solna                                                       *
  34.  * Sweden                                                               *
  35.  *                                                                      *
  36.  * FidoNet 2:201/328    email:dast@sth.frontec.se                       *
  37.  *                                                                      *
  38.  ************************************************************************/
  39.  
  40. #include <stddef.h>
  41. #include "script.h"
  42.  
  43. #if defined(UNIX)
  44. #include <stdio.h>
  45. #ifdef SUNOS
  46. #include <varargs.h>
  47. #else
  48. #include <stdarg.h>
  49. #endif
  50. #endif
  51.  
  52. #include "reference.h"
  53.  
  54. struct fplStr EmptyString={0,0,0};
  55.  
  56. #ifndef AMIGA /* if not using SAS/C on Amiga */
  57.  
  58. #ifdef VARARG_FUNCTIONS
  59.  
  60. /*
  61.  * The following stub functions to the actual library functions was done
  62.  * to make this run under SunOS 4.1.x using gcc. Thanks to Bernd Noll
  63.  * (b_noll@sun.rhrk.un) for this contribution!
  64.  */
  65.  
  66. long fplReferenceTags(void *anchor, void *refID, ...)
  67. {
  68.   va_list tags;
  69.   long ret;
  70. #ifdef SUNOS
  71.   va_start(tags); /* get parameter list */
  72. #else
  73.   va_start(tags, refID); /* get parameter list */
  74. #endif
  75.   ret = fplReference(anchor, refID, (unsigned long *)tags);
  76.   va_end(tags);
  77.   return ret;
  78. }
  79.  
  80. #else /* VARARG_FUNCTIONS */
  81.  
  82. long fplReferenceTags(void *anchor, void *refID, unsigned long tags, ...)
  83. {
  84.   return(fplReference(anchor, refID, &tags));
  85. }
  86.  
  87. #endif
  88.  
  89. #endif
  90.  
  91. /**********************************************************************
  92.  *
  93.  * fplReference()
  94.  *
  95.  * Handles all referencing to FPL internal symbols from the interface
  96.  * function.
  97.  *
  98.  ******/
  99.  
  100. ReturnCode PREFIX
  101. fplReference(AREG(0) struct Data *scr,
  102.              AREG(1) struct Identifier *ident,
  103.              AREG(2) unsigned long *tags)
  104. {
  105.   ReturnCode ret = FPL_OK;
  106.   long item=0;
  107.   long a=0;
  108.   long *dims;
  109.   long my_strlen=-1;
  110.   struct fplRef *ref;
  111.   while(tags && *tags) {
  112.     switch(*tags++) {
  113.     case FPLREF_ARRAY_RESIZE:        /* version 11 magic! */
  114.       if(ident->flags&FPL_VARIABLE && ident->data.variable.num) {
  115.         /*
  116.          * It is a variable and it is at least a one dimensional array!
  117.          */
  118.         ref = (struct fplRef *)(*tags);
  119.         CALL( ArrayResize(scr,
  120.                           ref->Dimensions,
  121.                           ref->ArraySize,
  122.                           ident));
  123.       }
  124.       break;
  125.       
  126.     case FPLREF_ARRAY_ITEM:
  127.       if(ident->flags&FPL_VARIABLE) {
  128.     dims = (long *)(*tags);
  129.     while(dims[a]>0)
  130.       a++;
  131.     item = ArrayNum(a, ident->data.variable.num,
  132.             dims, ident->data.variable.dims);
  133.     if(item<0)
  134.       item=0; /* just ignore stupid values! */
  135.         a=0; /* reset 'a' again */
  136.       }
  137.       break;
  138.     case FPLREF_ARRAY_INFO:
  139.       /*
  140.        * Fill out the structure given to us by the caller!
  141.        */
  142.       if(ident->flags&FPL_VARIABLE && ident->data.variable.num) {
  143.     ref = (struct fplRef *)(*tags);
  144.     ref->Dimensions = ident->data.variable.num;  /* number of dims */
  145.     ref->ArraySize  = ident->data.variable.dims; /* actual dims */
  146.       }
  147.       break;
  148.     case FPLREF_NAME:
  149.       /*
  150.        * Receive name in supplied char pointer!
  151.        */
  152.       *(uchar **)(*tags) = ident->name;
  153.       break;
  154.     case FPLREF_TYPE:
  155.       /*
  156.        * Receive flags in supplied long!
  157.        */
  158.       *(long *)(*tags) =
  159.         (ident->flags&FPL_STRING_VARIABLE?FPLREF_TYPE_STRING:0)|
  160.       (ident->flags&FPL_INT_VARIABLE?FPLREF_TYPE_INTEGER:0)|
  161.         (ident->flags&FPL_VARIABLE?
  162.          (ident->data.variable.num?FPLREF_TYPE_ARRAY:0):0 )|
  163.            (ident->flags&FPL_FUNCTION?FPLREF_TYPE_FUNCTION:0);
  164.       break;
  165.  
  166.     case FPLREF_GET_STRING:
  167.       if(ident->flags&FPL_STRING_VARIABLE &&
  168.      item<ident->data.variable.size) {
  169.         if(ident->data.variable.var.str[item]) {
  170.           /*
  171.            * This is a string!
  172.            */
  173.           *(uchar **)(*tags) = ident->data.variable.var.str[item]->string;
  174.         }
  175.         else {
  176.           /*
  177.            * Can't return NULL for no string, return pointer to ""!
  178.            */
  179.           *(uchar **)(*tags) = EmptyString.string;
  180.         }
  181.       }
  182.       else {
  183.     *(uchar **)(*tags) = NULL;
  184.       }
  185.       break;
  186.  
  187.     case FPLREF_SET_MY_STRLEN:
  188.       my_strlen=(long)(*tags);
  189.       break;
  190.     case FPLREF_SET_MY_STRING:
  191.       a=1;
  192.     case FPLREF_SET_STRING:
  193.       if(ident->flags&FPL_STRING_VARIABLE &&
  194.      item<ident->data.variable.size &&
  195.          *tags) {
  196.     /*
  197.      * Get the allocation type.
  198.      */
  199.     uchar type=MALLOC_DYNAMIC; /* default memory state */
  200.     struct fplStr *str;
  201.     if(ident->data.variable.var.str[item]) {
  202.       type = TypeMem(ident->data.variable.var.str[item]);
  203.  
  204.       if(MALLOC_STATIC == type ) {
  205.         /*
  206.          * The previous allocation was static!
  207.          */
  208.         FREEA( ident->data.variable.var.str[item] );
  209.       }
  210.           else {
  211.             FREE( ident->data.variable.var.str[item] );
  212.           }
  213.     }
  214.     if(1 == a) {
  215.       /*
  216.        * This is a FPLREF_SET_MY_STRING call. That means we got a regular
  217.        * C style char pointer to a zero terminated string here, allocate
  218.        * a regular FPL string and copy the string into that one
  219.        */
  220.       register long len = 0>my_strlen?strlen((uchar *)*tags):my_strlen;
  221.           GETMEM(str, len + sizeof(struct fplStr));
  222.           str->alloc= len;
  223.           str->len= len; /* set default to entire string */
  224.  
  225.           /* copy the data into the string */
  226.           memcpy(str->string, (uchar *)(*tags), len);
  227.     }
  228.     else {
  229.           /*
  230.            * We received a pointer to the ->string member of a fplStr struct.
  231.            * Make 'str' point to the struct itself!
  232.            */
  233.       str = (struct fplStr *)
  234.         (((uchar *)(*tags)) - offsetof(struct fplStr, string));
  235.         }
  236.  
  237.     ident->data.variable.var.str[item] = str;
  238.  
  239.         str->string[str->len] = '\0'; /* force zero termination! */
  240.     
  241.     if(MALLOC_STATIC == type || ident->flags&FPL_EXPORT_SYMBOL) {
  242.       /*
  243.        * The previous memory was static, which probably means that
  244.        * this is an exported or global variable which required
  245.        * static existance. Swap it back to that state!
  246.        */
  247.       SwapMem(scr,
  248.                   ident->data.variable.var.str[item],
  249.                   MALLOC_STATIC);
  250.     }
  251.         else {
  252.           /*
  253.            * Make sure this allocation is dynamic!
  254.            */
  255.       SwapMem(scr,
  256.                   ident->data.variable.var.str[item],
  257.                   MALLOC_DYNAMIC);
  258.         }
  259.       }
  260.       else {
  261.     *(uchar **)(*tags) = NULL;
  262.       }
  263.       break;
  264.  
  265.     case FPLREF_GET_INTEGER:
  266.       if(ident->flags&FPL_INT_VARIABLE &&
  267.      item<ident->data.variable.size) {
  268.     /* we supply a pointer to it, then we can return NULL if there was
  269.        something that looked fishy! */
  270.         *(long **)(*tags) = &ident->data.variable.var.val32[item];
  271.       }
  272.       else {
  273.     *(long **)(*tags) = NULL;
  274.       }
  275.       break;
  276.  
  277.     case FPLREF_SET_INTEGER:
  278.       if(ident->flags&FPL_INT_VARIABLE &&
  279.          item<ident->data.variable.size) {
  280.     /* set integer variable item */
  281.         ident->data.variable.var.val32[item] = (*tags);
  282.       }
  283.       break;
  284.     }
  285.     tags++;
  286.   }
  287.   return ret;
  288. }
  289.  
  290.